#!/bin/bash
########################################################################
# script name:  run_steps.sh
# Used for:
# Author:       Martin Dumont
# Contributors:
# Version:      0.1
#
# (date format: date +'%Y/%m/%d')
#
# Date          Version Contributors    Modifications
# ----------    ------- ------------    -------------
# 2012/05/02    0.1     MDUMONT         initial
########################################################################
usage()
{
cat << STOP

usage: $0 [options] [ARG]

This script is used for ....

OPTIONS:
   -c               Configuration file
   -x               Exclude step (comma seperated) [optional]
   -f               Force mode [optional]
Ex.:
$0 -c /central/depot/files/tl7_upgrade.conf
$0 -c /mnt/files/new_server.conf
$0 -f -c /central/depot/files/tl7_upgrade.conf 
$0 -c /central/depot/files/tl8_upgrade.conf -x 1,2
STOP
}
#######################################
# Get parameters
#######################################
while getopts c:x:f OPTION
do
	case $OPTION in
		c)
			CONFFILE=$OPTARG
			;;
		x)
			EXCLUDE=$(/bin/echo $OPTARG | sed 's/,/ /g')
			;;
		f)
			FORCE=1
			;;
		\?)
			usage
			exit 1
			;;
		*)
			usage
			exit 1
			;;
	esac
done
if [ $OPTIND = 1 ]; then usage; exit 1; fi
#######################################
# Variables
#######################################
umask 022
if [ "$(whoami)" != "root" ]; then echo "You need to be root (try with sudo)"; exit 1; fi
if [ -z "$CONFFILE" ]; then usage; exit 1; fi
if [ ! -f "$CONFFILE" ]; then /bin/echo "File $CONFFILE doesn't exist or is unreadable"; exit 1; fi
if [ -z "$EXCLUDE" ]; then EXCLUDE=0; fi
SSH_OPTS=" -o ConnectTimeout=15 -o BatchMode=yes -o StrictHostKeyChecking=no -o LogLevel=quiet"
. $CONFFILE
. $FUNCFILE
[[ ${LOGDIR?Error \$LOGDIR is not defined in $CONFFILE} ]]
[[ ${CHECKFILE?Error \$CHECKFILE is not defined in $CONFFILE} ]]
[[ ${STATUSFILE?Error \$STATUSFILE is not defined in $CONFFILE} ]]
if [ -z "${Order_a[0]}" ]; then /bin/echo "Order_a array looks empty"; exit 1; fi
if [ -f "$CHECKFILE" ]; then /bin/echo "Check file exist, $CHECKFILE\n\nPlease apply the changes and commit to repository.\n\nRemove the checkfile when done.\n"; exit 1; fi
if [ ! -x "$FUNCFILE" ]; then /bin/echo "File $FUNCTIONSFILE doesn't exist or is un-executable"; exit 1; fi
#######################################
#######################################
function log_status {
   DATE=$(date +'%Y-%m-%d-%H-%M-%S')
   STEP=$1; shift; FUNC=$1; shift; STATUS=$1; shift; LOG=$LOGDIR/function.$FUNC.log
	(
   /bin/echo "+----------------------------------------------------------------------------------------------------------+"
   /bin/echo "|CKPT|$STEP|$DATE|$FUNC|$STATUS|$LOG|$@"
   /bin/echo "+----------------------------------------------------------------------------------------------------------+"
	) | tee -a $STATUSFILE
}
#######################################
#######################################
function setup_steps {
	#######################################
	# List order and steps
	#######################################
	/bin/echo "Order of steps to execute: \n"

	index=0
	element_count=${#Order_a[@]}
	while [ "$index" -lt "$element_count" ]
	do
		function=$(echo ${Order_a[$index]} | cut -d: -f1)
		comment=$(echo ${Order_a[$index]} | cut -d: -f2)
		/bin/echo "Step $index: $function\t-> $comment" 
		((index++))
	done
	/bin/echo

	#######################################

	/bin/echo "Press any key to continue..."; read -n 1

	if [ ! -d $LOGDIR ]; then mkdir -m 755 -p $LOGDIR || exit; fi
	NUMSTEPS=${#Order_a[@]}
}
#######################################
#######################################
# FUNCTIONS
#######################################
#######################################
function set_starting_step {
	/bin/echo "+----------------------------------------------------------------------------------------------------------+"
	/bin/echo "| Initializing"
	/bin/echo "+----------------------------------------------------------------------------------------------------------+"
	/bin/echo
	RUNNINGSTEP=0
	if [ -f $STATUSFILE ]
	then
		/bin/echo "Found $STATUSFILE"
	   LASTLINE=$(cat $STATUSFILE | grep CKPT | tail -1)
	   LASTSTEPS=$(/bin/echo $LASTLINE | cut -d'|' -f3)
	   LASTSTATUS=$(/bin/echo $LASTLINE | cut -d'|' -f6)
		/bin/echo
	   /bin/echo "The last executed step was ${LASTSTEPS}/${NUMSTEPS} and the status was $LASTSTATUS"
		if [ "$LASTSTATUS" = "finish" ]; then NEXTSTEP=`expr $LASTSTEPS + 1`; else NEXTSTEP=$LASTSTEPS; fi
		/bin/echo "If you decide to continue, the script will start at step $NEXTSTEP"
		/bin/echo "If not, the script will ask you at what step you want to continue"
		/bin/echo
		read -n 1 -p "Do you want to continue with this script? [y/n]: "
		if [ "$REPLY" = "y" ]
		then
			/bin/echo
			/bin/echo "Setting starting step to $NEXTSTEP"
			RUNNINGSTEP=$NEXTSTEP
		else
			ASK=yes
			while [ "$ASK" = "yes" ]
			do
				/bin/echo
				read -p "Please enter starting step [from 1 to $NUMSTEPS]: "
				if [ -z "${REPLY##*[!0-9]*}" ]
				then
					/bin/echo "Starting step doesn't seems to be a number"
					continue
				fi
				if [ "$REPLY" -gt "$NUMSTEPS" ]
				then
					/bin/echo "Starting step ($REPLY) is higher then the total number of step ($NUMSTEPS)"
					continue
				fi
				ASK=no
				RUNNINGSTEP=$REPLY
			done
		fi
	else
		touch $STATUSFILE && chmod 755 $STATUSFILE
	fi
	/bin/echo
	/bin/echo "+----------------------------------------------------------------------------------------------------------+"
	/bin/echo
	/bin/echo "Total number of steps: $NUMSTEPS"
	/bin/echo "Starting step:         $RUNNINGSTEP"
	/bin/echo "Ending step:           $(expr $NUMSTEPS - 1)"
	/bin/echo
	/bin/echo "+----------------------------------------------------------------------------------------------------------+"
	/bin/echo
}
#######################################
#######################################
# MAIN
#######################################
set_variables
setup_steps
set_starting_step
index=$RUNNINGSTEP
while [ $index -lt $NUMSTEPS ]
do
	EXEC=yes
	if [ "$EXCLUDE" != "0" ]
	then
		for i in $EXCLUDE
		do
			if [ "$i" = "$index" ]; then EXEC=no; fi
		done
	fi
	################################################
	# exec_xxx should be something like exec_B1...
	################################################
	function=$(/bin/echo ${Order_a[$index]} | cut -d: -f1)
	comment=$(/bin/echo ${Order_a[$index]} | cut -d: -f2)
	if [ "$EXEC" = "yes" ]
	then
	   /bin/echo
		/bin/echo "Starting step $index: $function -> $comment"
		if [ -z "$FORCE" ]
			then
			/bin/echo "Press any key to continue or \"n\" to skip this step... \c"
		   read -n 1
		   /bin/echo
		else
			REPLY=y			
		fi
	   if [ "$REPLY" != "n" ]
	   then
			log_status $index $function begin $comment
			$function 2>&1 | tee $LOGDIR/function.$function.log
			if grep -q EXIT $LOGDIR/function.$function.log; then exit 1; fi
			log_status $index $function finish $comment
			if grep -q REBOOT-NOW $LOGDIR/function.$function.log; then /bin/echo "Please reboot"; exit 0; fi
		fi
	fi
	((index++))
done
#######################################
exit 0
